﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace TR0217.AboutToAdd
{
    public static class ColorManager
    {
        public static Color GetGradientColor(int index, int count, params Color[] clrs)
        {
            if (index < 0 || index >= count)
                throw new ArgumentOutOfRangeException("index必须在[0,cout)之间！");

            if(clrs.Length < 1)
                throw new ArgumentException("必须要有多于一个颜色！");

            double pos = ((double)(clrs.Length-1))*index /(count-1);
            int begin = (int)Math.Floor(pos);
            int end = begin==(clrs.Length-1)?begin:begin+1;

            Color clrbegin = clrs[begin];
            Color clrend = clrs[end];
            double endRatio = pos - begin;
            double beginRatio = 1.0 - endRatio;

            Byte R = (Byte)(beginRatio * clrbegin.R + endRatio * clrend.R);
            Byte G = (Byte)(beginRatio * clrbegin.G + endRatio * clrend.G);
            Byte B = (Byte)(beginRatio * clrbegin.B + endRatio * clrend.B);

            return Color.FromArgb(R, G, B);
        }

        public static Color GetDiscreteColor(int index, int count)
        {
            if (index < 0 || index >= count)
                throw new ArgumentOutOfRangeException("index必须在[0,cout)之间！");

            double hue = 360.0 * index / (count-1);
            double lightness = 0.5 * Math.Sqrt(index) / Math.Sqrt(count - 1);
            double saturation = 1;
            double r = lightness;
            double g = lightness;
            double b = lightness;
            if (saturation == 0)
                return Color.FromArgb(255, (int)(r * 255), (int)(g * 255), (int)(b * 255));

            double q = 0;
            if (lightness < 0.5)
                q = lightness * (1 + saturation);
            else
                q = lightness + saturation - (lightness * saturation);
            double p = 2 * lightness - q;
            double hk = hue / 360;

            // r,g,b colors
            double[] tc = new double[3] { hk + (1d / 3d), hk, hk - (1d / 3d) };
            double[] colors = new double[3] { 0, 0, 0 };

            for (int color = 0; color < colors.Length; color++)
            {
                if (tc[color] < 0)
                    tc[color] += 1;
                if (tc[color] > 1)
                    tc[color] -= 1;

                if (tc[color] < (1d / 6d))
                    colors[color] = p + ((q - p) * 6 * tc[color]);
                else
                    if (tc[color] >= (1d / 6d) && tc[color] < (1d / 2d))
                        colors[color] = q;
                    else
                        if (tc[color] >= (1d / 2d) && tc[color] < (2d / 3d))
                            colors[color] = p + ((q - p) * 6 * (2d / 3d - tc[color]));
                        else
                            colors[color] = p;

                colors[color] *= 255; // convert to value expected by Color
            }
            return Color.FromArgb(255, (int)colors[0], (int)colors[1], (int)colors[2]);
        }
    }
}
